package config

import (
	"fmt"
	"log"
	"strings"

	"code.byted.org/bytertc/whiteboard_server/biz/pkg/rabbit_mq"

	"code.byted.org/gopkg/env"
	"code.byted.org/middleware/hertz/byted/config/local"
	"github.com/spf13/viper"
)

// 不可以在结构体里使用指针
type AppConfig struct {
	MySQL           string           `viper:"MySQL.PSM"`
	DBName          string           `viper:"MySQL.DB"`
	DSN             string           `viper:"MySQL.DSN"`
	Redis           string           `viper:"Redis.PSM"`
	RTM             string           `viper:"RTM.PSM"`
	RTMPath         string           `viper:"RTM.Path"`
	RTC             string           `viper:"RTC.PSM"`
	SchedulerPsm    string           `viper:"Scheduler.PSM"`
	BillCluster     string           `viper:"Bill.Cluster"`
	BillTopic       string           `viper:"Bill.Topic"`
	Transcode       string           `viper:"Transcode.PSM"`
	TranscodePath   string           `viper:"Transcode.Path"`
	Record          string           `viper:"Record.PSM"`
	RecordPath      string           `viper:"Record.Path"`
	Token           string           `viper:"Token.PSM"`
	TokenPath       string           `viper:"Token.Path"`
	StorageConfig   StorageConfig    `viper:"StorageConfig"`
	RabbitConfig    rabbit_mq.Config `viper:"RabbitConfig"`
	NodeServer      string           `viper:"NodeServer"`
	DynamicCallback string           `viper:"DynamicCallback"`
}

type StorageConfig struct {
	VolcApiHost     string `viper:"VolcApiHost"`
	VolcRtcAk       string `viper:"VolcRtcAk"`
	VolcRtcSk       string `viper:"VolcRtcSk"`
	BytePlusApiHost string `viper:"BytePlusApiHost"`
	BytePlusRtcAk   string `viper:"BytePlusAk"`
	BytePlusRtcSk   string `viper:"BytePlusSk"`
	VolcEndPoint    string `viper:"VolcEndPoint"`
}

const (
	productMode = "Product"
	developMode = "Develop"
)

var sConfig AppConfig

func NewConfig() AppConfig {
	v := viper.New()
	v.AddConfigPath(local.ConfigDir)
	v.SetConfigName(strings.ReplaceAll(env.PSM(), ".", "_"))
	err := v.ReadInConfig()
	if err != nil {
		panic(err)
	}

	mode := developMode
	if env.IsProduct() {
		mode = productMode
	}
	vv := v.Sub(mode)
	if vv == nil {
		panic(fmt.Sprintf("fail to get config in %s mode", mode))
	}

	sConfig = AppConfig{}
	err = viperParse(&sConfig, vv)
	if err != nil {
		panic(err)
	}

	vvv := vv.Sub("RabbitConfig")
	err = viperParse(&sConfig.RabbitConfig, vvv)
	if err != nil {
		panic(err)
	}

	log.Printf("AppConfig:%#v", sConfig)

	return sConfig
}

func GetConfig() AppConfig {
	return sConfig
}
